home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
SGI Developer Toolbox 6.1
/
SGI Developer Toolbox 6.1 - Disc 4.iso
/
public
/
plan
/
src
/
print.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-08-01
|
15KB
|
622 lines
/*
** Create and destroy the print popup. It is installed when the
** Print entry in the File pulldown in the main calendar window
** is used.
**
** create_print_popup()
** destroy_print_popup()
*/
#include <stdio.h>
#include <time.h>
#include <signal.h>
#include <Xm/Xm.h>
#include <Xm/DialogS.h>
#include <Xm/Form.h>
#include <Xm/Frame.h>
#include <Xm/RowColumn.h>
#include <Xm/LabelP.h>
#include <Xm/LabelG.h>
#include <Xm/PushBP.h>
#include <Xm/PushBG.h>
#include <Xm/ToggleB.h>
#include <Xm/TextF.h>
#include <Xm/Protocols.h>
#include "cal.h"
#include <fcntl.h>
#include <errno.h>
#define PS_LIB "plan_cal.ps"
extern void help_callback();
extern char *parse_holidays();
extern struct tm *time_to_tm();
extern int set_icon();
extern int create_error_popup();
extern BOOL lookup_entry(), lookup_next_entry();
extern int curr_month, curr_year, curr_week;
extern struct holiday holiday[];
extern struct holiday sm_holiday[];
extern Display *display; /* everybody uses the same server */
extern struct config config; /* global configuration data */
extern struct list *mainlist; /* list of all schedule entries */
extern Pixel color[NCOLS]; /* colors: COL_* */
extern char Print_Spooler[100];/* defined in file_r.c */
extern Widget mainwindow; /* popup menus hang off main window */
/* char *Default_Spooler = "lp -s -T ps"; */
#ifdef PS_SPOOLER
char *Default_Spooler = PS_SPOOLER;
#else /* PS_SPOOLER */
# ifdef sgi
char *Default_Spooler = "lp";
# else /* sgi */
char *Default_Spooler = "lpr";
# endif /* sgi */
#endif /* PS_SPOOLER */
static BOOL popup_created = FALSE; /* popup exists if TRUE */
static Widget print_shell; /* popup menu shell */
static Widget spool_text; /* Spool String Text Widget */
#define PR_YEAR 0
#define PR_MONTH 1
#define PR_WEEK 2
#define PR_DAY 3
static int print_mode = 0;
int Print_Calendar();
static int Print_Day();
static void OutStr();
static void mode_callback(), print_callback(), done_callback();
/*
** create a print popup as a separate application shell. When the popup
** already exists and was just popped down, pop it up and exit. This ensures
** that it comes up with the same defaults.
*/
void
create_print_popup()
{
Widget print_form, w;
Widget mode_frame, mode_form, mode_radio;
Widget spool_frame, spool_form;
Widget action_area;
Atom closewindow;
char tmp[32];
int n;
if(popup_created) {
XtPopup(print_shell, XtGrabNone);
return;
}
print_shell = XtVaAppCreateShell("Print", "plan",
applicationShellWidgetClass, display,
XmNdeleteResponse, XmDO_NOTHING,
XmNiconic, False,
NULL);
set_icon(print_shell, 1);
print_form = XtCreateManagedWidget("printform", xmFormWidgetClass,
print_shell, NULL, 0);
XtAddCallback(print_form,
XmNhelpCallback, help_callback, (XtPointer)"print");
mode_frame = XtVaCreateManagedWidget("mode",
xmFrameWidgetClass, print_form,
XmNtopAttachment, XmATTACH_FORM,
XmNtopOffset, 8,
XmNrightAttachment, XmATTACH_FORM,
XmNrightOffset, 8,
XmNleftAttachment, XmATTACH_FORM,
XmNleftOffset, 8,
NULL, 0);
mode_form = XtCreateManagedWidget("print_mode", xmFormWidgetClass,
mode_frame, NULL, 0);
/* Print Mode */
w = XtVaCreateManagedWidget("Print Mode:",
xmLabelWidgetClass, mode_form,
XmNtopAttachment, XmATTACH_FORM,
XmNtopOffset, 16,
XmNleftAttachment, XmATTACH_FORM,
XmNleftOffset, 16,
NULL);
mode_radio = XmVaCreateSimpleRadioBox(mode_form, "radio",
0, mode_callback,
XmNtopAttachment, XmATTACH_FORM,
XmNtopOffset, 16,
XmNleftAttachment, XmATTACH_WIDGET,
XmNleftWidget, w,
XmNleftOffset, 16,
XmNspacing, 4,
XmVaRADIOBUTTON, NULL, 0, NULL, NULL,
XmVaRADIOBUTTON, NULL, 0, NULL, NULL,
#ifdef NOT_YET
XmVaRADIOBUTTON, NULL, 0, NULL, NULL,
XmVaRADIOBUTTON, NULL, 0, NULL, NULL,
#endif
NULL);
XtManageChild(mode_radio);
/* Set resources for each toggleButton... */
#ifdef NOT_YET
for(n = 0;n < 4;n++) {
#else
for(n = 0;n < 2;n++) {
#endif
sprintf(tmp, "button_%d", n);
if((w = XtNameToWidget(mode_radio, tmp)) != NULL) {
XtVaSetValues(w, XmNselectColor, color[COL_TOGGLE], NULL);
}
}
/* Spool String */
spool_frame = XtVaCreateManagedWidget("spool",
xmFrameWidgetClass, print_form,
XmNtopAttachment, XmATTACH_WIDGET,
XmNtopOffset, 8,
XmNtopWidget, mode_frame,
XmNleftAttachment, XmATTACH_FORM,
XmNleftOffset, 8,
XmNrightAttachment, XmATTACH_FORM,
XmNrightOffset, 8,
NULL);
spool_form = XtCreateManagedWidget("spool_form", xmFormWidgetClass,
spool_frame, NULL, 0);
w = XtVaCreateManagedWidget("Spooler String:",
xmLabelWidgetClass, spool_form,
XmNtopAttachment, XmATTACH_FORM,
XmNtopOffset, 8,
XmNbottomAttachment,XmATTACH_FORM,
XmNbottomOffset, 8,
XmNleftAttachment, XmATTACH_FORM,
XmNleftOffset, 16,
NULL);
if (!*Print_Spooler) {
strcpy(Print_Spooler, Default_Spooler);
mainlist->modified = TRUE;
}
spool_text = XtVaCreateManagedWidget("spooler",
xmTextFieldWidgetClass, spool_form,
XmNtopAttachment, XmATTACH_FORM,
XmNtopOffset, 8,
XmNleftAttachment, XmATTACH_WIDGET,
XmNleftOffset, 8,
XmNleftWidget, w,
XmNbackground, color[COL_TEXTBACK],
XmNvalue, Print_Spooler,
NULL);
/* Buttons */
action_area = XtVaCreateManagedWidget("action",
xmFormWidgetClass, print_form,
XmNfractionBase, 10,
XmNtopAttachment, XmATTACH_WIDGET,
XmNtopOffset, 16,
XmNtopWidget, spool_frame,
XmNbottomAttachment, XmATTACH_FORM,
XmNbottomOffset, 16,
XmNleftAttachment, XmATTACH_FORM,
XmNleftOffset, 4,
XmNrightAttachment, XmATTACH_FORM,
XmNrightOffset, 4,
NULL);
w = XtVaCreateManagedWidget("Print",
xmPushButtonWidgetClass, action_area,
XmNtopAttachment, XmATTACH_POSITION,
XmNtopPosition, 0,
XmNbottomAttachment, XmATTACH_POSITION,
XmNbottomPosition, 10,
XmNleftAttachment, XmATTACH_POSITION,
XmNleftPosition, 7,
XmNrightAttachment, XmATTACH_POSITION,
XmNrightPosition, 9,
NULL);
XtAddCallback(w, XmNactivateCallback, print_callback, (XtPointer)0);
XtAddCallback(w, XmNhelpCallback, help_callback, (XtPointer)"print_print");
w = XtVaCreateManagedWidget("Cancel",
xmPushButtonWidgetClass, action_area,
XmNtopAttachment, XmATTACH_POSITION,
XmNtopPosition, 0,
XmNbottomAttachment, XmATTACH_POSITION,
XmNbottomPosition, 10,
XmNleftAttachment, XmATTACH_POSITION,
XmNleftPosition, 4,
XmNrightAttachment, XmATTACH_POSITION,
XmNrightPosition, 6,
NULL);
XtAddCallback(w, XmNactivateCallback, done_callback, (XtPointer)0);
XtAddCallback(w, XmNhelpCallback, help_callback,
(XtPointer)"print_cancel");
w = XtVaCreateManagedWidget("Help",
xmPushButtonWidgetClass, action_area,
XmNtopAttachment, XmATTACH_POSITION,
XmNtopPosition, 0,
XmNbottomAttachment, XmATTACH_POSITION,
XmNbottomPosition, 10,
XmNleftAttachment, XmATTACH_POSITION,
XmNleftPosition, 1,
XmNrightAttachment, XmATTACH_POSITION,
XmNrightPosition, 3,
NULL);
XtAddCallback(w, XmNactivateCallback, help_callback,(XtPointer)"print");
XtAddCallback(w, XmNhelpCallback, help_callback,(XtPointer)"print");
XtPopup(print_shell, XtGrabNone);
closewindow = XmInternAtom(display, "WM_DELETE_WINDOW", False);
XmAddWMProtocolCallback(print_shell, closewindow, done_callback,
(XtPointer)print_shell);
popup_created = TRUE;
}
/* Waste popup if it's been created */
void
destroy_print_popup()
{
if(popup_created) {
XtPopdown(print_shell);
}
}
/*ARGSUSED*/
static void
mode_callback(widget, item, data)
Widget widget;
int item;
XmToggleButtonCallbackStruct *data;
{
print_mode = item;
}
/*ARGSUSED*/
static void
done_callback(widget, item, data)
Widget widget;
int item;
XmToggleButtonCallbackStruct *data;
{
destroy_print_popup();
}
static void broken_pipe_handler(sig)
{
create_error_popup(mainwindow, 0,
"Print failed, aborted with signal %d\n", sig);
signal(SIGPIPE, SIG_IGN);
}
/*ARGSUSED*/
static void
print_callback(widget, item, data)
Widget widget;
int item;
XmToggleButtonCallbackStruct *data;
{
FILE *pp;
char *Spooler = XmTextFieldGetString(spool_text);
char tmp[128];
signal(SIGPIPE, broken_pipe_handler);
sprintf(tmp, "exec %s", Spooler);
#if 0
fprintf(stderr, "print_callback: Mode = %d, Cmd = [%s]\n", print_mode, tmp);
fprintf(stderr, "curr_year = %d\n", curr_year);
fprintf(stderr, "curr_month = %d\n", curr_month);
#endif
/* Note any changes to spooler. */
if(strcmp(Spooler, Print_Spooler)) {
strcpy(Print_Spooler, Spooler);
mainlist->modified = TRUE;
}
if((pp = popen(tmp, "w")) == NULL)
create_error_popup(print_shell, errno, "Cannot open pipe to \"%s\"",
tmp);
else
Print_Calendar(pp, print_mode, curr_month, 1, curr_year);
destroy_print_popup();
signal(SIGPIPE, SIG_DFL);
}
int
Print_Calendar(Fp, Mode, Month, Day, Year)
FILE *Fp;
int Mode;
int Month, Day, Year;
{
int Pslib_Fd;
char *cp;
char tmp[512];
char PsLib[1024];
int nb;
int WeekDay, WeekNum, JulDay;
int CDay, StartDay, EndDay;
int CYear, StartYear, EndYear;
int CMonth, StartMonth, EndMonth;
char *Mode_Str;
find_file(PsLib, PS_LIB, FALSE);
if((Pslib_Fd = open(PsLib, O_RDONLY)) == -1) {
int error = errno;
create_error_popup(print_shell, error, "Can't open %s", PsLib);
pclose(Fp);
return(-1);
}
StartMonth = EndMonth = Month;
StartDay = 1; EndDay = 31;
StartYear = EndYear = Year;
switch(Mode) {
case PR_YEAR:
Mode_Str = "Year";
Month = 0;
StartMonth = 0;
EndMonth = 11;
break;
case PR_MONTH:
Mode_Str = "Month";
break;
case PR_WEEK:
Mode_Str = "Week";
break;
case PR_DAY:
Mode_Str = "Day";
StartDay = EndDay = Day;
break;
default:
pclose(Fp);
return(-2);
}
WeekDay = -1;
date_to_time(1, Month, Year, &WeekDay, &WeekNum, &JulDay);
if(Mode == PR_WEEK) {
StartDay = Day - WeekDay;
EndDay = StartDay + 6;
}
fprintf(Fp, "%%!PS-Adobe\n");
fprintf(Fp, "%%\n");
fprintf(Fp, "%%%%Creator: plan\n");
fprintf(Fp, "%%%%Title: %s Calendar\n", Mode_Str);
fprintf(Fp, "%%%%EndComments\n");
fprintf(Fp, "%%\n");
fprintf(Fp, "%% Begin of PS_LIB (%s)\n", PsLib);
while((nb = read(Pslib_Fd, tmp, sizeof(tmp))) > 0)
fwrite(tmp, sizeof(char), nb, Fp);
close(Pslib_Fd);
fprintf(Fp, "%% End of PS_LIB (%s)\n", PsLib);
fflush(Fp);
fprintf(Fp, "\n%% Plan Configuration values...\n");
#define BOOL_TO_PS(a,b) \
fprintf(Fp, "%s %s def\n", a, (b ? "true" : "false"))
BOOL_TO_PS("/SundayFirst", config.sunday_first);
BOOL_TO_PS("/MMDDYY", config.mmddyy);
BOOL_TO_PS("/AMPM", config.ampm);
BOOL_TO_PS("/Print_Julian", config.julian);
BOOL_TO_PS("/Print_WeekNum", config.weeknum);
#undef BOOL_TO_PS
fprintf(Fp, "\n%% Print Information\n");
fprintf(Fp, "/Print_Mode (%s) def\n", Mode_Str);
fprintf(Fp, "/Month %d def\n", Month + 1);
fprintf(Fp, "/Day %d def\n", Day);
fprintf(Fp, "/Year %d def\n", Year + 1900);
fprintf(Fp, "/WeekDay %d def\n", WeekDay);
fprintf(Fp, "/WeekNum %d def\n", WeekNum);
fprintf(Fp, "/JulDay %d def\n", JulDay);
fprintf(Fp, "\n");
fprintf(Fp, "%% Month Range: %2d thru %2d\n", StartMonth+1, EndMonth+1);
fprintf(Fp, "%% Day Range : %2d thru %2d\n", StartDay, EndDay);
fprintf(Fp, "%% Year Range : %2d thru %2d\n", StartYear, EndYear);
fprintf(Fp, "\nInitCal\n\n");
fprintf(Fp, "%% Data...\n\n");
for(CYear = StartYear;CYear <= EndYear;CYear++) {
if((cp = parse_holidays(CYear, FALSE)) != NULL) {
create_error_popup(print_shell, 0, cp);
pclose(Fp);
return(-3);
}
for(CMonth = StartMonth;CMonth <= EndMonth;CMonth++)
for(CDay = StartDay;CDay <= EndDay;CDay++)
Print_Day(Fp, CDay, CMonth, CYear);
StartMonth = 1;
EndMonth = 12;
}
fprintf(Fp, "\n");
fprintf(Fp, "FinishCal\n");
pclose(Fp);
return(0);
}
static int
Print_Day(Fp, Day, Month, Year)
FILE *Fp;
int Day, Month, Year;
{
int DayStart, DayEnd, WeekNum, JulDay, Found;
struct entry *Entry;
struct holiday *Hp;
struct lookup lookup;
struct tm *tm;
char *Holidays[3];
int NumHolidays;
char tmp[32];
if(!(DayStart = date_to_time(Day, Month, Year, NULL, &JulDay, &WeekNum)))
return(-1);
DayEnd = DayStart + 86399;
NumHolidays = 0;
/* Check Holidays */
if((Hp = &sm_holiday[JulDay])->string != NULL && *Hp->string)
Holidays[NumHolidays++] = Hp->string;
if((Hp = &holiday[JulDay])->string != NULL && *Hp->string)
Holidays[NumHolidays++] = Hp->string;
fprintf(Fp, "%d %d %d %d %d NewDay\n",
Month+1, Day, Year, WeekNum+1, JulDay+1);
if(NumHolidays > 0) {
int i;
fprintf(Fp, "[ ");
for(i = 0;i < NumHolidays;) {
OutStr(Fp, Holidays[i]);
if(++i < NumHolidays)
fprintf(Fp, "\n ");
}
fprintf(Fp, " ] PaintHolidays\n");
}
Found = lookup_entry(&lookup, mainlist, DayStart, TRUE, FALSE);
for(;Found;Found = lookup_next_entry(&lookup)) {
Entry = &mainlist->entry[lookup.index];
/* Skip notes begining with '-' or '=' */
if(Entry->note && (*Entry->note == '-' || *Entry->note == '='))
continue;
/* Only look at today's entries */
if(lookup.index >= mainlist->nentries
|| lookup.trigger < DayStart
|| lookup.trigger > DayEnd)
break;
/* TODO: Add removal of past entries.. */
/* Output Entry */
tm = time_to_tm(Entry->time);
fprintf(Fp, " ");
if(config.mmddyy)
fprintf(Fp, " (%02d/%02d/%02d)\t",
tm->tm_mon+1, tm->tm_mday, tm->tm_year % 100);
else
fprintf(Fp, " (%d.%d.%02d)\t",
tm->tm_mday, tm->tm_mon+1, tm->tm_year % 100);
if(Entry->notime)
fprintf(Fp, "()");
else {
if(config.ampm)
fprintf(Fp, "(%2d:%02d%c)\t", tm->tm_hour%12 ? tm->tm_hour%12 : 12,
tm->tm_min,
tm->tm_hour < 12 ? 'a' : 'p');
else
fprintf(Fp, "(%02d:%02d)\t", tm->tm_hour, tm->tm_min);
}
OutStr(Fp, Entry->note);
if(Entry->message && *Entry->message) {
fprintf(Fp, "\n ");
OutStr(Fp, Entry->message);
fprintf(Fp, "\n PaintEntry\n");
} else
fprintf(Fp, "\t() PaintEntry\n");
fflush(Fp);
}
fflush(Fp);
return(0);
}
/* Output a string in a manner compatible with PostScript.. */
static void
OutStr(Fp, Str)
FILE *Fp;
char *Str;
{
/* Not perfect but It'll work for now... */
putc('(', Fp);
for(;Str && *Str;Str++)
switch(*Str) {
case '\n':
/* String trailing New Lines */
if(!*(Str+1))
break;
/* Replace Newlines we spaces... */
/* In the "PostScript" we output an escaped newline */
/* to improve readability */
putc(' ', Fp);
case '\\': case '(': case ')':
fprintf(Fp, "\\%c", *Str);
break;
case '\f': fprintf(Fp, "\\f"); break;
case '\r': fprintf(Fp, "\\r"); break;
default:
putc(*Str, Fp);
break;
}
putc(')', Fp);
}